/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.store.client.subcomponents;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;

import com.elf.gwt.common.client.GWTCommerceCommonConstants;
import com.elf.gwt.common.client.callback.SubComponentCallback;
import com.elf.gwt.common.client.model.AccountMetaModel;
import com.elf.gwt.common.client.model.AccountModel;
import com.elf.gwt.common.client.model.AddressModel;
import com.elf.gwt.common.client.model.CountryModel;
import com.elf.gwt.common.client.subcomponent.CaptchaSubComponent;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.elf.gwt.store.client.GWTCommerceConstants;
import com.elf.gwt.store.client.StoreComponentController;
import com.elf.gwt.store.client.components.AccountComponent;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

/**
 *  Create a new account
 *  TBD - throttling of account creation
 */
public class AccountCreateSubComponent extends StoreSubComponent
{	
	protected AccountMetaModel accountMetaModel;
	protected AddressModel addressModel;

	protected InlineHTML warningLabel;
	protected ListBox countryListBox;
	protected ListBox stateListBox;
	
	protected HashMap<String, Widget> elements = null;

	DateTimeFormat dtformat;

	/**
	 * Constructor
	 */
	public AccountCreateSubComponent(
			StoreComponentController controller, 
			AddressModel amodel,
			SubComponentCallback callback, 
			String superAction)
	{
		super(controller, "AccountComponent", superAction, callback);
		elements = new HashMap<String, Widget>();

		if (accountComponent == null) accountComponent = (AccountComponent)controller.getComponent("AccountComponent");
		accountMetaModel = accountComponent.getAccountMetaModel();
		AccountModel accountModel = accountComponent.getAccountModel();
		this.addressModel = amodel;

		thisComponent.add(new InlineHTML("<br/>"));
		warningLabel = new InlineHTML();
		warningLabel.setStyleName("WarningLabel");
		warningLabel.addStyleName(handle + "WarningLabel");
		thisComponent.add(warningLabel);

		GWTCommerceConstants constants = controller.getStoreConstants();

		if (superAction.equals(AccountComponent.CreateAccount))
		{
			InlineHTML returnToLogin = new InlineHTML(constants.AccountComponentReturnToLogin());
			InlineHTML loginPage = new InlineHTML(constants.AccountComponentLoginPage());
			loginPage.setStyleName("ComponentLink");
			loginPage.addStyleName("AccountComponentLoginPageLink");
			loginPage.addClickHandler(
					new ClickHandler() {
						public void onClick(ClickEvent event) {
							setSuperAction(AccountComponent.LoginAccount);
							getCallback().onNavigate(thisComponent);
						}}
			);
			HorizontalPanel loginMessagePanel = new HorizontalPanel();
			loginMessagePanel.add(returnToLogin);
			loginMessagePanel.add(loginPage);
			thisComponent.add(loginMessagePanel);
			thisComponent.add(new InlineHTML("<br/>"));
		}

		if (superAction.equals(AccountComponent.CreateAccount) || superAction.equals(AccountComponent.EditAccount) || superAction.equals(AccountComponent.AddressBook))
		{
			InlineLabel detailsTitle = new InlineLabel(constants.AccountComponentYourPersonalDetails());
			detailsTitle.setStyleName(handle + "SubTitle");
			InlineLabel requiredTitle = new InlineLabel(constants.AccountComponentRequired());
			requiredTitle.setStyleName(handle + "RequiredTitle");
			HorizontalPanel detailsTitlePanel = new HorizontalPanel();
			detailsTitlePanel.setStyleName(handle + "DetailsTitlePanel");
			detailsTitlePanel.add(detailsTitle);
			detailsTitlePanel.add(requiredTitle);
			thisComponent.add(detailsTitlePanel);
			detailsTitlePanel.setWidth("100%");
			detailsTitlePanel.setCellHorizontalAlignment(requiredTitle, HasHorizontalAlignment.ALIGN_RIGHT);

			int gridrows = 2;
			if (accountMetaModel.isDisplayGender()) gridrows++;
			if (superAction.equals(AccountComponent.CreateAccount) || superAction.equals(AccountComponent.EditAccount))
			{
				if (accountMetaModel.isDisplayDOB()) gridrows++;
				gridrows++;
			}
			Grid detailsGrid = new Grid(gridrows,3);
			detailsGrid.setWidth("100%");
			detailsGrid.setStyleName(handle + "SubPanel");
			detailsGrid.getColumnFormatter().setStyleName(0, handle + "SubPanelCol0");
			thisComponent.add(detailsGrid);

			int gridrow = 0;
			if (accountMetaModel.isDisplayGender())
			{
				RadioButton genderMButton = new RadioButton("gender1", constants.AccountComponentMale());
				RadioButton genderFButton = new RadioButton("gender1", constants.AccountComponentFemale());
				elements.put("genderM", genderMButton);
				elements.put("genderF", genderFButton);
				HorizontalPanel genderPanel = new HorizontalPanel();
				genderPanel.add(genderMButton);
				genderPanel.add(genderFButton);

				if (superAction.equals(AccountComponent.AddressBook))
				{
					if (accountModel.getGender().equals("f"))
					{
						genderFButton.setValue(true);
						genderMButton.setValue(false);
					}
					else if (accountModel.getGender().equals("m"))
					{
						genderFButton.setValue(false);
						genderMButton.setValue(true);
					}
				}
				else
				{
					if (amodel.getGender().equals("f"))
					{
						genderFButton.setValue(true);
						genderMButton.setValue(false);
					}
					else if (amodel.getGender().equals("m"))
					{
						genderFButton.setValue(false);
						genderMButton.setValue(true);
					}
				}
				CommonUtils.addGridWidget(handle, gridrow, genderPanel, detailsGrid, "gender", constants.AccountComponentGender(), constants.AccountComponentGenderText());
				gridrow++;
			}

			TextBox firstnameBox = new TextBox(); 
			elements.put("firstname", firstnameBox);
			CommonUtils.addGridWidget(handle, gridrow, firstnameBox, detailsGrid, "firstname", constants.AccountComponentFirstname(), constants.AccountComponentFirstnameText());
			if (superAction.equals(AccountComponent.AddressBook))firstnameBox.setText(amodel.getFirstname());
			else firstnameBox.setText(accountModel.getFirstname());
			gridrow++;

			TextBox lastnameBox = new TextBox(); 
			elements.put("lastname", lastnameBox);
			CommonUtils.addGridWidget(handle, gridrow, lastnameBox, detailsGrid, "lastname", constants.AccountComponentLastname(), constants.AccountComponentLastnameText());
			if (superAction.equals(AccountComponent.AddressBook))lastnameBox.setText(amodel.getLastname());
			else lastnameBox.setText(accountModel.getLastname());
			gridrow++;

			if (superAction.equals(AccountComponent.CreateAccount) || superAction.equals(AccountComponent.EditAccount))
			{
				if (accountMetaModel.isDisplayDOB())
				{
					dtformat = DateTimeFormat.getFormat(constants.AccountComponentDateOfBirthFormat());
					TextBox dobBox = new TextBox(); 
					elements.put("dob", dobBox);
					CommonUtils.addGridWidget(handle, gridrow, dobBox, detailsGrid, "dob1", constants.AccountComponentDateOfBirth(), constants.AccountComponentDateOfBirthText() + dtformat.getPattern());
					try {
						dobBox.setText(dtformat.format(accountModel.getDateOfBirth()));
					}
					catch (Exception dte){}
					gridrow++;
				}

				TextBox emailBox = new TextBox(); 
				elements.put("email", emailBox);
				CommonUtils.addGridWidget(handle, gridrow, emailBox, detailsGrid, "email_address", constants.AccountComponentEmailAddress(), constants.AccountComponentEmailAddressText());
				emailBox.setText(accountModel.getEmailAddress());
			}

			if (superAction.equals(AccountComponent.CreateAccount) || superAction.equals(AccountComponent.AddressBook))
			{
				if (accountMetaModel.isDisplayCompany())
				{
					thisComponent.add(new InlineHTML("<br/>"));
					CommonUtils.addSubTitle(handle, thisComponent, constants.AccountComponentCompanyDetails());

					Grid companyGrid = new Grid(1,3);
					companyGrid.setWidth("100%");
					companyGrid.setStyleName(handle + "SubPanel");
					companyGrid.getColumnFormatter().setStyleName(0, handle + "SubPanelCol0");
					thisComponent.add(companyGrid);

					TextBox companyBox = new TextBox(); 
					elements.put("company", companyBox);
					CommonUtils.addGridWidget(handle,0, companyBox, companyGrid, "company", constants.AccountComponentCompany(), constants.AccountComponentCompanyText());
					companyBox.setText(amodel.getCompany());
				}
			}
		}

		if (superAction.equals(AccountComponent.CreateAccount) || superAction.equals(AccountComponent.AddressBook))
		{
			thisComponent.add(new InlineHTML("<br/>"));
			CommonUtils.addSubTitle(handle, thisComponent, constants.AccountComponentYourAddress());

			int gridrows = 4;
			if (accountMetaModel.isDisplaySuburb()) gridrows++;
			if (accountMetaModel.isDisplayState()) gridrows++;
			Grid addressGrid = new Grid(gridrows,3);

			addressGrid.setWidth("100%");
			addressGrid.setStyleName(handle + "SubPanel");
			addressGrid.getColumnFormatter().setStyleName(0, handle + "SubPanelCol0");
			thisComponent.add(addressGrid);

			int gridrow = 0;
			countryListBox = new ListBox();
			elements.put("country", countryListBox);
			countryListBox.addChangeHandler(new ChangeHandler() {
				public void onChange(ChangeEvent event) {
					if (accountComponent.getAccountMetaModel().isDisplayState())
					{
						CountryModel cmodel = accountComponent.getAccountMetaModel().getCountryModels().get(countryListBox.getSelectedIndex());
						String countryName = cmodel.getName();
						if (accountMetaModel.isDisplayState()) CommonUtils.updateStateListBox(countryName, null, accountComponent.getAccountMetaModel().getCountryModels(), stateListBox);	
					}
				}
			});
			CommonUtils.addGridWidget(handle, gridrow, countryListBox, addressGrid, "country", constants.AccountComponentCountry(), constants.AccountComponentCountryText());

			Iterator<CountryModel> iter = accountMetaModel.getCountryModels().iterator();
			int i = 0;
			while(iter.hasNext())
			{
				CountryModel cmodel = iter.next();
				countryListBox.addItem(cmodel.getName(),cmodel.getName());
				if (cmodel.getName().equals(amodel.getCountry()))
					countryListBox.setItemSelected(i, true);
				else
					countryListBox.setItemSelected(i, false);
				i++;
			}

			gridrow++;

			TextBox streetBox = new TextBox(); 
			elements.put("street", streetBox);
			CommonUtils.addGridWidget(handle, gridrow, streetBox, addressGrid, "street_address", constants.AccountComponentStreetAddress(), constants.AccountComponentStreetAddressText());
			streetBox.setText(amodel.getStreet());
			gridrow++;

			if (accountMetaModel.isDisplaySuburb())
			{
				TextBox suburbBox = new TextBox(); 
				elements.put("suburb", suburbBox);
				CommonUtils.addGridWidget(handle, gridrow, suburbBox, addressGrid, "suburb", constants.AccountComponentSuburb(), constants.AccountComponentSuburbText());
				suburbBox.setText(amodel.getSuburb());
				gridrow++;
			}

			TextBox cityBox = new TextBox(); 
			elements.put("city", cityBox);
			CommonUtils.addGridWidget(handle, gridrow, cityBox, addressGrid, "city", constants.AccountComponentCity(), constants.AccountComponentCityText());
			cityBox.setText(amodel.getCity());
			gridrow++;

			if (accountMetaModel.isDisplayState())
			{
				stateListBox = new ListBox();
				elements.put("state", stateListBox);
				CommonUtils.addGridWidget(handle, gridrow, stateListBox, addressGrid, "state", constants.AccountComponentState(), constants.AccountComponentStateText());
				CommonUtils.updateStateListBox(amodel.getCountry(), amodel.getState(), accountMetaModel.getCountryModels(), stateListBox);
				gridrow++;
			}

			TextBox postCodeBox = new TextBox(); 
			elements.put("postcode", postCodeBox);
			CommonUtils.addGridWidget(handle, gridrow, postCodeBox, addressGrid, "postcode", constants.AccountComponentPostCode(), constants.AccountComponentPostCodeText());
			postCodeBox.setText(amodel.getPostcode());
			gridrow++;
		}

		if (superAction.equals(AccountComponent.CreateAccount) || superAction.equals(AccountComponent.EditAccount))
		{
			thisComponent.add(new InlineHTML("<br/>"));
			CommonUtils.addSubTitle(handle, thisComponent, constants.AccountComponentYourContactInformation());

			Grid contactGrid = new Grid(2,3);
			contactGrid.setWidth("100%");
			contactGrid.setStyleName(handle + "SubPanel");
			contactGrid.getColumnFormatter().setStyleName(0, handle + "SubPanelCol0");
			thisComponent.add(contactGrid);

			int gridrow = 0;
			TextBox telephoneBox = new TextBox(); 
			elements.put("telephone", telephoneBox);
			CommonUtils.addGridWidget(handle, gridrow, telephoneBox, contactGrid, "telephone", constants.AccountComponentTelephoneNumber(), constants.AccountComponentTelephoneNumberText());
			telephoneBox.setText(accountModel.getTelephone());
			gridrow++;

			TextBox faxBox = new TextBox(); 
			elements.put("fax", faxBox);
			CommonUtils.addGridWidget(handle, gridrow, faxBox, contactGrid, "fax", constants.AccountComponentFaxNumber(), constants.AccountComponentFAXNumberText());
			faxBox.setText(accountModel.getFax());		
		}

		if (superAction.equals(AccountComponent.CreateAccount))
		{
			thisComponent.add(new InlineHTML("<br/>"));
			CommonUtils.addSubTitle(handle, thisComponent, constants.AccountComponentOptions());

			Grid optionsGrid = new Grid(1,3);
			optionsGrid.setWidth("100%");
			optionsGrid.setStyleName(handle + "SubPanel");
			optionsGrid.getColumnFormatter().setStyleName(0, handle + "SubPanelCol0");
			thisComponent.add(optionsGrid);

			CheckBox newsletterBox = new CheckBox();
			elements.put("newsletter", newsletterBox);
			CommonUtils.addGridWidget(handle,0, newsletterBox, optionsGrid, "newsletter", constants.AccountComponentNewsletter(),"");
			newsletterBox.setValue(accountModel.isNewsletter());
		}

		if (superAction.equals(AccountComponent.CreateAccount) || superAction.equals(AccountComponent.ChangePassword))
		{
			thisComponent.add(new InlineHTML("<br/>"));
			CommonUtils.addSubTitle(handle, thisComponent, constants.AccountComponentYourPassword());

			Grid passwordGrid = new Grid(2,3);
			passwordGrid.setWidth("100%");
			passwordGrid.setStyleName(handle + "SubPanel");
			passwordGrid.getColumnFormatter().setStyleName(0, handle + "SubPanelCol0");
			thisComponent.add(passwordGrid);

			int gridrow = 0;
			PasswordTextBox password1Box = new PasswordTextBox(); 
			elements.put("password1", password1Box);
			CommonUtils.addGridWidget(handle, gridrow, password1Box, passwordGrid, "password", constants.AccountComponentPassword(), constants.AccountComponentPasswordText());
			gridrow++;

			PasswordTextBox password2Box = new PasswordTextBox(); 
			elements.put("password2", password2Box);
			CommonUtils.addGridWidget(handle, gridrow, password2Box, passwordGrid, "confirmation", constants.AccountComponentPasswordConfirmation(), constants.AccountComponentPasswordConfirmationText());
			gridrow++;
		}

		if (superAction.equals(AccountComponent.CreateAccount))
		{
			CaptchaSubComponent captchaSubComponent = new CaptchaSubComponent(getController());
			elements.put("captcha", captchaSubComponent);
			thisComponent.add(captchaSubComponent);
		}


		thisComponent.add(new InlineHTML("<br/><br/>"));
		HorizontalPanel hpanel = new HorizontalPanel();

		Button editButton = new Button(controller.getCommonConstants().Continue(), 
				new ClickHandler() {
					public void onClick(ClickEvent event) {
						AccountCreateSubComponent comp = (AccountCreateSubComponent)thisComponent;
						comp.submit();
					}}
		);
		hpanel.add(editButton);

		if (superAction.startsWith("Edit") || superAction.equals(AccountComponent.ChangePassword)
				|| superAction.equals(AccountComponent.AddressBook))
		{
			Button cancelButton = new Button(controller.getCommonConstants().GoBack(), 
					new ClickHandler() {
						public void onClick(ClickEvent event) {
							if (getSuperAction().startsWith("Edit") || getSuperAction().equals(AccountComponent.ChangePassword))
							{
								setSuperAction(AccountComponent.ViewAccount);
							}
							getCallback().onNavigate(thisComponent);
						}}
			);
			hpanel.add(cancelButton);
			hpanel.setCellHorizontalAlignment(cancelButton, HasHorizontalAlignment.ALIGN_RIGHT);
		}
		hpanel.setWidth("100%");
		thisComponent.add(hpanel);
	}


	/**
	 * build
	 */
	public void build() 
	{
		AccountModel accountModel = accountComponent.getAccountModel();

		warningLabel.setHTML("");
		GWTCommerceConstants constants = controller.getStoreConstants();
		GWTCommerceCommonConstants commonConstants = controller.getCommonConstants();
		int id = accountModel.getErrorCode();

		GWT.log("AccountCreateSubComponent.build errorCode " + id, null);
		if (id == 0 && accountModel.getId() > 0 && superAction.equals(AccountComponent.CreateAccount))
		{
			setSuperAction(AccountComponent.ViewAccount);
			getCallback().onNavigate(thisComponent);
		}
		if (id == 1)
		{
			warningLabel.setHTML("<span class = \"successLabel\">"+controller.getCommonConstants().Success()+"</span>");
		}
		if (id > -1 && accountModel.getId() > 0)
		{
		}
		else if (id == 0)
		{
			warningLabel.setHTML("");
		}
		else if (id == -37)
		{
			warningLabel.setHTML(commonConstants.CaptchaSessionNotFound() + "<br/>");
		}
		else if (id == -38)
		{
			warningLabel.setHTML(commonConstants.CaptchaCodeNotMatch() + "<br/>");
		}
		else if (id == -43)
		{
			warningLabel.setHTML(constants.AccountComponentEmailAddressCheckError() + "<br/>");
		}
		else if (id == -50)
		{
			warningLabel.setHTML(constants.AccountComponentAccountAlreadyExists() + "<br/>");
		}
		else if (id == -60)
		{
			warningLabel.setHTML(constants.AccountComponentAccountDoesNotExists() + "<br/>");
		}
		else if (id == -70)
		{
			warningLabel.setHTML(constants.AccountComponentEmailDoesNotMatchId() + "<br/>");
		}
		else if (id == -80)
		{
			warningLabel.setHTML(constants.AccountComponentAddressDoesnNotExist() + "<br/>");
		}
		else if (id == -90)
		{
			warningLabel.setHTML(constants.AccountComponentTooManyAddresses() + "<br/>");
		}
		else
		{
			warningLabel.setHTML(constants.AccountComponentUnknownError() + " " + id + "<br/>");
		}
		if (id < 0) Window.scrollTo(0, 0);

		accountModel.setErrorCode(0);

		CaptchaSubComponent captchaSubComponent = (CaptchaSubComponent) elements.get("captcha");
		if (captchaSubComponent != null) {
			
			captchaSubComponent.build();
		}
	}

	/**
	 * validate prior to form submission
	 */
	public void submit() 
	{
		AccountMetaModel accountMetaModel = accountComponent.getAccountMetaModel();
		AccountModel accountModel = accountComponent.getAccountModel();
		GWT.log("submit superAction " + superAction, null);
		try {
			GWTCommerceConstants constants = controller.getStoreConstants();
			GWTCommerceCommonConstants commonConstants = controller.getCommonConstants();
			//Validations
			StringBuffer warningText = new StringBuffer();

			RadioButton genderMButton = (RadioButton) elements.get("genderM");
			RadioButton genderFButton = (RadioButton) elements.get("genderF");
			if (genderMButton != null && genderFButton != null) {
				if (!genderMButton.getValue() && !genderFButton.getValue()) {
					warningText.append(constants.AccountComponentGenderError());
				}
				else if (genderMButton.getValue()) {
					if (!superAction.equals(AccountComponent.AddressBook)) accountModel.setGender("m");
					if (addressModel != null) addressModel.setGender("m");
				}
				else if (genderFButton.getValue()) {
					if (!superAction.equals(AccountComponent.AddressBook)) accountModel.setGender("f");
					if (addressModel != null) addressModel.setGender("f");
				}
			}

			TextBox firstnameBox = (TextBox)elements.get("firstname");
			if (firstnameBox != null) {
				warningText = CommonUtils.lengthWarning(commonConstants, warningText, firstnameBox, 
						constants.AccountComponentFirstname(), accountMetaModel.getEntryFirstnameLengthMin());
				if (warningText.length() == 0) {
					if (!superAction.equals(AccountComponent.AddressBook)) accountModel.setFirstname(firstnameBox.getText());
					if (addressModel != null) addressModel.setFirstname(firstnameBox.getText());
				}				
			}

			TextBox lastnameBox = (TextBox)elements.get("lastname");
			if (lastnameBox != null) {
				warningText = CommonUtils.lengthWarning(commonConstants, warningText, lastnameBox, 
						constants.AccountComponentLastname(), accountMetaModel.getEntryLastnameLengthMin());
				if (warningText.length() == 0) {
					if (!superAction.equals(AccountComponent.AddressBook)) accountModel.setLastname(lastnameBox.getText());
					if (addressModel != null) addressModel.setLastname(lastnameBox.getText());
				}				
			}
			
			TextBox dobBox = (TextBox)elements.get("dob");
			if (dobBox != null) {
				String strDOB = dobBox.getText();
				if (strDOB != null && strDOB.length() > 0) {
					try {
						Date dateDOB = dtformat.parse(strDOB);
						dobBox.setText(dtformat.format(dateDOB));
						accountModel.setDateOfBirth(dateDOB);
					}
					catch(Exception exception) {
						if (warningText.length() > 0)warningText.append("\n");
						warningText.append(constants.AccountComponentDateOfBirthError());
					}
				}				
			}
			
			TextBox emailBox = (TextBox) elements.get("email");
			if (emailBox != null) {
				warningText = CommonUtils.lengthWarning(commonConstants, warningText, emailBox, 
						constants.AccountComponentEmailAddress(), accountMetaModel.getEntryEmailAddressLengthMin());
				if (warningText.length() == 0) {
					if (accountMetaModel.isEntryEmailAddressFormatCheck() && !CommonUtils.validateEmailFormat(emailBox.getText())) {
						warningText.append("\n");
						warningText.append(constants.AccountComponentEmailAddressCheckError());
					}
				}

				if (warningText.length() == 0) accountModel.setEmailAddress(emailBox.getText());
			}
			
			TextBox companyBox = (TextBox) elements.get("company");
			if (companyBox != null) {
				addressModel.setCompany(companyBox.getText());
			}
			
			TextBox streetBox = (TextBox) elements.get("street");
			if (streetBox != null) {
				warningText = CommonUtils.lengthWarning(commonConstants, warningText, streetBox, 
						constants.AccountComponentStreetAddress(), accountMetaModel.getEntryStreetAddressLengthMin());
				if (warningText.length() == 0) addressModel.setStreet(streetBox.getText());
			}
			
			TextBox postCodeBox = (TextBox) elements.get("postcode");
			if (postCodeBox != null) {
				warningText = CommonUtils.lengthWarning(commonConstants, warningText, postCodeBox, 
						constants.AccountComponentPostCode(), accountMetaModel.getEntryPostCodeLengthMin());
				if (warningText.length() == 0) addressModel.setPostcode(postCodeBox.getText());
			}
			
			TextBox cityBox = (TextBox) elements.get("city");
			if (cityBox != null) {
				warningText = CommonUtils.lengthWarning(commonConstants, warningText, cityBox, 
						constants.AccountComponentCity(), accountMetaModel.getEntryCityLengthMin());
				if (warningText.length() == 0) addressModel.setCity(cityBox.getText());
			}
			
			TextBox suburbBox = (TextBox) elements.get("suburb");
			if (suburbBox != null) {
				addressModel.setSuburb(suburbBox.getText());
			}
			
			if (superAction.equals(AccountComponent.CreateAccount) || superAction.equals(AccountComponent.AddressBook))
			{
				addressModel.setCountry(countryListBox.getValue(countryListBox.getSelectedIndex()));
				if (accountMetaModel.isDisplayState()) addressModel.setState(stateListBox.getValue(stateListBox.getSelectedIndex()));
			}

			TextBox telephoneBox = (TextBox) elements.get("telephone");
			if (telephoneBox != null) {
				warningText = CommonUtils.lengthWarning(commonConstants, warningText, telephoneBox, 
						constants.AccountComponentTelephoneNumber(), accountMetaModel.getEntryTelephoneNumberLengthMin());
				if (warningText.length() == 0) accountModel.setTelephone(telephoneBox.getText());				
			}
			TextBox faxBox = (TextBox) elements.get("fax");
			if (faxBox != null) {
				accountModel.setFax(faxBox.getText());
			}
			
			CheckBox newsletterBox = (CheckBox) elements.get("newsletter");
			if (newsletterBox != null) {
				accountModel.setNewsletter(newsletterBox.getValue());
			}

			CaptchaSubComponent captchaSubComponent = (CaptchaSubComponent) elements.get("captcha");
			if (captchaSubComponent != null)
			{
				String captchaCode = captchaSubComponent.getCaptchaCode();
				if (captchaCode.length() < 5)
				{
					StringBuffer sb = new StringBuffer(CommonUtils.lengthWarning(commonConstants, commonConstants.CaptchaSecurityCode(), 5));
					warningText.append(sb).append("\n");
				}
				else
				{
					accountModel.setCaptchaCode(captchaSubComponent.getCaptchaCode());
					accountModel.setCaptchaSession(captchaSubComponent.getCaptchaSession());
				}
			}
			
			PasswordTextBox password1Box = (PasswordTextBox) elements.get("password1");
			PasswordTextBox password2Box = (PasswordTextBox) elements.get("password2");
			if (password1Box != null && password2Box != null) {
				if (!password1Box.getText().equals(password2Box.getText()))
				{
					if (warningText.length() > 0)warningText.append("\n");
					warningText.append(constants.AccountComponentPasswordErrorNotMatching());
				}
				warningText = CommonUtils.lengthWarning(commonConstants, warningText, password1Box, 
						constants.AccountComponentPassword(), accountMetaModel.getEntryPasswordLengthMin());
				if (warningText.length() == 0) accountModel.setPassword(password1Box.getText());				
			}

			if (warningText.length() > 0)
				Window.alert(warningText.toString());
			else
			{
				if (password2Box != null) password2Box.setText("");
				getCallback().onSuccess(thisComponent);
				if (password1Box != null) password1Box.setText("");
			}
		}
		catch (Exception e) 
		{
			GWT.log("AccountCreateSubComponent.submit", e);
		}
	}
}
